package com.ruibang.glass.material.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruibang.glass.common.domain.GlobalUser;
import com.ruibang.glass.common.domain.produce.BucketShipmentRecord;
import com.ruibang.glass.frequencycontrol.annotation.RedissonLock;
import com.ruibang.glass.material.constant.Constants;
import com.ruibang.glass.material.constant.MaterialErrorCode;
import com.ruibang.glass.material.domain.req.BucketLoadReq;
import com.ruibang.glass.material.domain.req.BucketManagerReq;
import com.ruibang.glass.material.domain.req.BucketUnloadReq;
import com.ruibang.glass.material.domain.req.ContainerTransferReq;
import com.ruibang.glass.material.domain.resp.GlassContainerWarehouseInfo;
import com.ruibang.glass.material.entity.BucketManager;
import com.ruibang.glass.material.entity.ContainerTransferRecord;
import com.ruibang.glass.material.feign.ProduceApi;
import com.ruibang.glass.material.mapper.BucketManagerMapper;
import com.ruibang.glass.material.service.BucketManagerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruibang.glass.material.service.ContainerTransferRecordService;
import com.ruibang.glass.material.service.MaterialWarehouseInfoService;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import com.teaming.cloud.framework2.common.model.ResultBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 料罐管理 服务实现类
 * </p>
 *
 * @author songJinKang
 * @since 2024-03-26
 */
@Service
public class BucketManagerServiceImpl extends ServiceImpl<BucketManagerMapper, BucketManager> implements BucketManagerService {


    @Autowired
    private ContainerTransferRecordService containerTransferRecordService;

    @Autowired
    private ProduceApi produceApi;

    @Autowired
    private CommonService commonService;

    @Autowired
    private MaterialWarehouseInfoService materialWarehouseInfoService;

    @Override
    public void deleteById(String id) {
        lambdaUpdate().eq(BucketManager::getId, id).set(BucketManager::getIsDelete, Constants.ONE_STR).update();
    }
    @Override
    public IPage<BucketManager> pageQuery(BucketManagerReq bucketManagerReq) {
        QueryWrapper<BucketManager> qw = new QueryWrapper<>();
        qw.lambda().eq(BucketManager::getIsDelete, Constants.ZERO_STR);

        Page<BucketManager> page = baseMapper.pageQuery(new Page<>(bucketManagerReq.getPageNo(), bucketManagerReq.getPageSize()),bucketManagerReq);
        if (page != null && CollectionUtils.isNotEmpty(page.getRecords())) {
            List<BucketManager> bucketManager = page.getRecords();
            for (BucketManager manager : bucketManager) {
                if (Constants.ZERO_STR.equals(manager.getStatus()) && manager.getLoadTime() != null) {
                    Duration duration = Duration.between(manager.getLoadTime(), LocalDateTime.now());
                    long hours = duration.toHours();
                    manager.setUnloadStatus(hours >= 2 ? Constants.ONE_STR : Constants.ZERO_STR);
                }
            }
        }
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultBody transfer(ContainerTransferReq containerTransferReq) {
        //获取容器
        String containerId = containerTransferReq.getContainerId();
        BucketManager bucketManager = this.getById(containerId);
        if (bucketManager == null) {
            return ResultBody.fail(MaterialErrorCode.CONTAINER_NOT_FOUND.getCode(), MaterialErrorCode.CONTAINER_NOT_FOUND.getMsg());
        }
        //判断容器是否启用
        if (Constants.ZERO_STR.equals(bucketManager.getIsUse())) {
            return ResultBody.fail(MaterialErrorCode.BUCKET_IS_NOT_USE.getCode(), String.format(MaterialErrorCode.BUCKET_IS_NOT_USE.getMsg(), "转移"));
        }

        //根据库位码获取库位、仓库信息
        String warehousePositionCode = containerTransferReq.getWarehousePositionCode();
        GlassContainerWarehouseInfo glassContainerWarehouseInfo = materialWarehouseInfoService.getWarehouseInfoByWarehousePositionCode(warehousePositionCode);
        if (glassContainerWarehouseInfo == null || StringUtils.isBlank(glassContainerWarehouseInfo.getWarehouseId()) || StringUtils.isBlank(glassContainerWarehouseInfo.getWarehousePositionId())) {
            return ResultBody.fail(MaterialErrorCode.WAREHOUSE_OR_POSITION_IS_NULL.getCode(), MaterialErrorCode.WAREHOUSE_OR_POSITION_IS_NULL.getMsg());
        }

        bucketManager.setWarehouseId(glassContainerWarehouseInfo.getWarehouseId());
        bucketManager.setWarehousePositionId(glassContainerWarehouseInfo.getWarehousePositionId());
        //修改容器信息
        this.updateById(bucketManager);

        //保存容器转移记录
        ContainerTransferRecord containerTransferRecord = new ContainerTransferRecord();
        containerTransferRecord.setContainerCode(bucketManager.getContainerCode());
        containerTransferRecord.setContainerType(Constants.THREE_STR);
        containerTransferRecord.setTransferTime(LocalDateTime.now());
        containerTransferRecord.setWarehouseId(glassContainerWarehouseInfo.getWarehouseId());
        containerTransferRecord.setWarehousePositionId(glassContainerWarehouseInfo.getWarehousePositionId());
        containerTransferRecord.setWarehouseName(glassContainerWarehouseInfo.getWarehouseName());
        containerTransferRecord.setWarehousePositionName(glassContainerWarehouseInfo.getWarehousePositionName());
        //获取用户信息
        GlobalUser user = commonService.getUser();
        if (user != null) {
            containerTransferRecord.setTransferUserName(user.getName());
            containerTransferRecord.setTransferUserId(user.getUserId());
        }
        containerTransferRecordService.save(containerTransferRecord);

        return ResultBody.success();
    }

    @Override
    public void insert(BucketManager bucketManager) {
        try {
            bucketManager.setStatus(Constants.ONE_STR);
            bucketManager.setIsDelete(Constants.ZERO_STR);
            this.save(bucketManager);
        } catch (Exception e) {
            if (e instanceof DuplicateKeyException) {
                throw new ServiceException(MaterialErrorCode.CONTAINER_CODE_REPEAT.getCode(), MaterialErrorCode.CONTAINER_CODE_REPEAT.getMsg());
            }
            throw new ServiceException(MaterialErrorCode.SAVE_CONTAINER_FAIL.getCode(), MaterialErrorCode.SAVE_CONTAINER_FAIL.getMsg());
        }
    }

    @Override
    public ResultBody edit(BucketManager bucketManager) {
        BucketManager oldBucketManager = this.getById(bucketManager.getId());
        if (oldBucketManager == null) {
            return ResultBody.fail(MaterialErrorCode.BUCKET_NOT_FOUNT.getCode(), String.format(MaterialErrorCode.BUCKET_NOT_FOUNT.getMsg(), "修改"));
        }
        if (bucketManager.getIsUse().equals(Constants.ZERO_STR) && oldBucketManager.getStatus().equals(Constants.ZERO_STR)) {
            return ResultBody.fail(MaterialErrorCode.CURRENT_BUCKET_IS_USE.getCode(), MaterialErrorCode.CURRENT_BUCKET_IS_USE.getMsg());
        }
        //修改料罐
        try {
            //更新人
            GlobalUser user = commonService.getUser();
            if (user != null && com.alibaba.excel.util.StringUtils.isNotBlank(user.getUserId())) {
                bucketManager.setUpdateUserId(user.getUserId());
                bucketManager.setUpdateUserName(user.getName());
            }
            this.updateById(bucketManager);
        } catch (Exception e) {
            if (e instanceof DuplicateKeyException) {
                throw new ServiceException(MaterialErrorCode.CONTAINER_CODE_REPEAT.getCode(), MaterialErrorCode.CONTAINER_CODE_REPEAT.getMsg());
            }
            throw new ServiceException(MaterialErrorCode.SAVE_CONTAINER_FAIL.getCode(), MaterialErrorCode.SAVE_CONTAINER_FAIL.getMsg());
        }
        return ResultBody.success();
    }

    @Override
    @RedissonLock(key = "#bucketLoadReq.containerId")
    @Transactional(rollbackFor = Exception.class)
    public ResultBody load(BucketLoadReq bucketLoadReq) {
        BucketManager bucketManager = this.getById(bucketLoadReq.getContainerId());
        //未找到容器
        if (bucketManager == null) {
            return ResultBody.fail(MaterialErrorCode.BUCKET_NOT_FOUNT.getCode(), String.format(MaterialErrorCode.BUCKET_NOT_FOUNT.getMsg(), "装料"));
        }
        //判断容器是否启用
        if (Constants.ZERO_STR.equals(bucketManager.getIsUse())) {
            return ResultBody.fail(MaterialErrorCode.BUCKET_IS_NOT_USE.getCode(), String.format(MaterialErrorCode.BUCKET_IS_NOT_USE.getMsg(), "装料"));
        }
        //状态必须为空罐
        if (bucketManager.getStatus().equals(Constants.ZERO_STR)) {
            return ResultBody.fail(MaterialErrorCode.CURRENT_BUCKET_NOT_EMPTY.getCode(), MaterialErrorCode.CURRENT_BUCKET_NOT_EMPTY.getMsg());
        }
        //根据当前库位码获取库位
        String warehousePositionCode = bucketLoadReq.getWarehousePositionCode();
        GlassContainerWarehouseInfo glassContainerWarehouseInfo = materialWarehouseInfoService.getWarehouseInfoByWarehousePositionCode(warehousePositionCode);
        if (glassContainerWarehouseInfo == null || com.alibaba.excel.util.StringUtils.isBlank(glassContainerWarehouseInfo.getWarehouseId()) || StringUtils.isBlank(glassContainerWarehouseInfo.getWarehousePositionId())) {
            return ResultBody.fail(MaterialErrorCode.WAREHOUSE_OR_POSITION_IS_NULL.getCode(), MaterialErrorCode.WAREHOUSE_OR_POSITION_IS_NULL.getMsg());
        }

        //保存装料记录
        LocalDateTime now = LocalDateTime.now();
        BucketShipmentRecord bucketShipmentRecord = new BucketShipmentRecord();
        bucketShipmentRecord.setContainer(bucketManager.getContainerName());
        bucketShipmentRecord.setMaterial(bucketLoadReq.getMaterialName());
        bucketShipmentRecord.setNum(bucketLoadReq.getNum());
        bucketShipmentRecord.setLoadTime(now);
        bucketShipmentRecord.setFormulaCode(bucketLoadReq.getFormulaCode());
        bucketShipmentRecord.setLoadWarehousePosition(glassContainerWarehouseInfo.getWarehousePositionName());
        GlobalUser user = commonService.getUser();
        if (user != null) {
            bucketShipmentRecord.setLoadOperator(user.getName());
            bucketShipmentRecord.setLoadOperatorId(user.getUserId());
        }
        ResultBody<String> resultBody = produceApi.save(bucketShipmentRecord);
        if (resultBody != null && StringUtils.isNotBlank(resultBody.getData())) {
            String recordId = resultBody.getData();
            bucketManager.setRecordId(recordId);
        } else {
            return ResultBody.fail(MaterialErrorCode.UNLOAD_RECORD_SAVE_FAIL.getCode(), MaterialErrorCode.UNLOAD_RECORD_SAVE_FAIL.getMsg());
        }

        //修改料罐状态
        bucketManager.setStatus(Constants.ZERO_STR);
        bucketManager.setLoadTime(now);
        bucketManager.setUnLoadTime(null);
        this.updateById(bucketManager);
        return ResultBody.success();
    }

    @Override
    @RedissonLock(key = "#bucketUnloadReq.containerId")
    @Transactional(rollbackFor = Exception.class)
    public ResultBody unLoad(BucketUnloadReq bucketUnloadReq) {
        BucketManager bucketManager = this.getById(bucketUnloadReq.getContainerId());
        //未找到容器
        if (bucketManager == null) {
            return ResultBody.fail(MaterialErrorCode.BUCKET_NOT_FOUNT.getCode(), String.format(MaterialErrorCode.BUCKET_NOT_FOUNT.getMsg(), "卸料"));
        }
        //状态不可为空罐
        if (bucketManager.getStatus().equals(Constants.ONE_STR)) {
            return ResultBody.fail(MaterialErrorCode.CURRENT_BUCKET_NOT_EMPTY.getCode(), MaterialErrorCode.CURRENT_BUCKET_NOT_EMPTY.getMsg());
        }
        //根据当前库位码获取库位
        String warehousePositionCode = bucketUnloadReq.getWarehousePositionCode();
        GlassContainerWarehouseInfo glassContainerWarehouseInfo = materialWarehouseInfoService.getWarehouseInfoByWarehousePositionCode(warehousePositionCode);
        if (glassContainerWarehouseInfo == null || com.alibaba.excel.util.StringUtils.isBlank(glassContainerWarehouseInfo.getWarehouseId()) || StringUtils.isBlank(glassContainerWarehouseInfo.getWarehousePositionId())) {
            return ResultBody.fail(MaterialErrorCode.WAREHOUSE_OR_POSITION_IS_NULL.getCode(), MaterialErrorCode.WAREHOUSE_OR_POSITION_IS_NULL.getMsg());
        }

        //卸料状态
        Duration duration = Duration.between(bucketManager.getLoadTime(), LocalDateTime.now());
        long hours = duration.toHours();
        if (hours >= 2) {
            bucketUnloadReq.setAbnormalStatus(Constants.ZERO_STR);
            bucketUnloadReq.setAbnormalCause(null);
        } else {
            if (StringUtils.isBlank(bucketUnloadReq.getAbnormalCause())) {
                return ResultBody.fail(MaterialErrorCode.ABNORMAL_CAUSE_NOT_EMPTY.getCode(), MaterialErrorCode.ABNORMAL_CAUSE_NOT_EMPTY.getMsg());
            }
            bucketUnloadReq.setAbnormalStatus(Constants.ONE_STR);
        }

        //修改装装料记录
        LocalDateTime now = LocalDateTime.now();
        ResultBody<BucketShipmentRecord> resultBody = produceApi.getById(bucketManager.getRecordId());
        if (resultBody != null) {
            BucketShipmentRecord bucketShipmentRecord = resultBody.getData();
            bucketShipmentRecord.setUnloadTime(now);
            bucketShipmentRecord.setUnloadWarehousePosition(glassContainerWarehouseInfo.getWarehousePositionName());
            bucketShipmentRecord.setAbnormalStatus(bucketUnloadReq.getAbnormalStatus());
            bucketShipmentRecord.setAbnormalCause(bucketUnloadReq.getAbnormalCause());
            //获取用户信息
            GlobalUser user = commonService.getUser();
            if (user != null) {
                bucketShipmentRecord.setUnloadOperator(user.getName());
                bucketShipmentRecord.setUnloadOperatorId(user.getUserId());
            }
            produceApi.edit(bucketShipmentRecord);
        }

        //修改料罐状态
        bucketManager.setStatus(Constants.ONE_STR);
        bucketManager.setLoadTime(null);
        bucketManager.setUnLoadTime(now);
        bucketManager.setRecordId(null);
        this.updateById(bucketManager);
        return ResultBody.success();
    }


}
